'''
Created on 25 Oct 2012

@author: quirino.brizi
'''
from Queue import Queue, Empty
from org.codesketch.loadit.common import Runner, AsyncHTTPRequestHandler, \
    AsyncRequestGenerator
from org.codesketch.loadit.configuration.domain import Configuration
from org.codesketch.loadit.decorator import selfType, accepts
from time import sleep as _sleep, time as _time
from org.codesketch.loadit.utils import generateParametersCombination

class LinearRunner(Runner):
    '''
    Runner implementation execute request to the target server linearly
    '''
    
    def execute(self):
        writer = self._writer()
        conf = self._configuration()
        # test duration in seconds
        duration = conf.getTest().getDuration() * 60
        stopOnNoMoreRequest = conf.getScript().getParameter("stopOnNoMoreRequest") == "true"
        
        asyncReqHandler = AsyncHTTPRequestHandler(5, writer)
        asyncReqHandler.start()
        
        asyncReqGenerator = AsyncGetRequestGenerator(conf)
        asyncReqGenerator.start()
        
        start = _time()
        while duration > (_time() - start) :
            try :
                baseUrl, relativeUrl, params = asyncReqGenerator.request()
            except Empty :
                '''
                TODO: there are no more requests or the test duration is wrong?
                ''' 
                if stopOnNoMoreRequest : 
                    break 
                else : 
                    continue
            asyncReqHandler.get(baseUrl, relativeUrl, params)
            _sleep(0.01)
        
        asyncReqGenerator.stop()
        asyncReqHandler.stop()


class AsyncGetRequestGenerator(AsyncRequestGenerator):
    '''
    Asynchronously generates HTTP GET requests
    '''
    
    def __init__(self, conf):
        AsyncRequestGenerator.__init__(self, conf)
        self.__stop = False
        self.__queue = Queue()
        
    def request(self):
        '''
        Access point for retrieving requests
        '''
        request = self.__queue.get(timeout=5)
        self.__queue.task_done()
        return request
    
    def _generate(self):
        '''
        Generate requests
        '''
        target = self._getConfiguration().getTest().getTarget();
        address = target.getAddresses().pop(0)
        baseUrl = address.getBaseUrl()
        params = address.getParameters()
        comb = generateParametersCombination(params);
        for qs in comb :
            if self.__stop : break
            self.__queue.put_nowait([baseUrl, "", qs])
        del comb
        
    def stop(self) : self.__stop = True
    